<template>
  <div>
    <input type="text" v-model="fname" />
    <input type="text" v-model="lname" />
    <h2>{{ fname + lname }}</h2>
    <!-- 基于 字符串绑定（在 hooks 编程中不推荐使用了！） -->
    <h2 ref="myh2">{{ aname }}</h2>
    <!-- 大家注意：这个叫使用 对象的方法来绑定 ref 属性，它会自动关联到我们 js 中声明的 ref 对象 -->
    <h2 ref="myh2ref">{{ aname }}</h2>
    <hr>
    <input type="text" v-model="state.name" />
    <h2>{{ state.namelength }}</h2>
  </div>
</template>

<!-- 这个语法糖，不用再写一个 setup 的函数，更难得是不需要一堆 return 意大利面条 -->
<script setup>
// import axios from "axios"
import { GetMsg } from '../apis/apis'
import { ref, computed, reactive, watch, watchEffect, onMounted, getCurrentInstance, onUpdated, onUnmounted } from 'vue'
// 切记切记！使用 ref 创造的响应式对象，一定要使用 vule 属性进行调用
const fname = ref("12");
const lname = ref("12");
const aname = computed(() => {
  return fname.value + lname.value;
})

// 在 Vue3 中，没有 this 对象，可以使用 ctx 代表上下文，也代表当前组件的对象
// 注意：ctx 上下文 对象，在使用的时候，你要思考一下，是不是必须的？一般情况下，不需要使用这个
const { ctx } = getCurrentInstance();
console.log(ctx);

const myh2ref = ref(null)

// 如果我不希望在 onMounted 里面发请求
const getMsgIno = async () => {
  let res = await GetMsg();
  console.log(res);
}
getMsgIno()

GetMsg().then(res => {
  console.log(res);
}).catch(err => { });

(async () => {
  let res = await GetMsg();
  console.log(res);
})();


onMounted(async () => {
  console.log("页面被挂载了！");
  console.log(ctx.$refs.myh2);
  // 切记：ref 声明的响应式对象，在 js 中调用 需要使用 value 
  console.log(myh2ref.value);
  // let res = await GetMsg();
  // console.log(res);
})

// 我们并不推荐 updated 逻辑，因为它是脏监听，所有的响应式数据对象都要触发，无端的会消耗很多
onUpdated(() => {
  console.log(myh2ref.value);
})

onUnmounted(() => {
  // 如果我们页面中有 计时器、自定义事件等 回调的函数，销毁了页面，如果不手动的清除
  // 就会造成 内存泄漏
  // clearTimeout()
})

// 使用 reactive 创造响应式数据对象的写法
const state = reactive({
  name: "前端老兵",
  namelength: computed(() => {
    return state.name.length;
  })
})

// watch 监听
watch(fname, (newVal, oldVal) => {
  // console.log("fname 发生了变化", newVal, oldVal);
})

// 注意如果监听 state 数据需要使用 回调函数
// ？为什么 直接使用 state.name 监听无法触发？？？
watch(() => state.name, (newVal, oldVal) => {
  // console.log("state name 发生了变化", newVal, oldVal);
})


// 监听多个值，注意如果是 state 数据需要使用 回调函数
watch([fname, lname], (newVal, oldVal) => {
  // console.log("fname 发生了变化", newVal, oldVal);
}, {
  deep: true,
  // 立即监听执行
  immediate: true
})

watchEffect(() => {
  // 副作用监听，程序初始化的时候运行一次，类似于 created 状态完成
  // console.log("数据发生了变化！");
})

</script>

<style lang="scss" scoped></style>